package com.bbva.gptf.back.dominio;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import oracle.jdbc.driver.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;

import org.apache.commons.dbcp.DelegatingConnection;
import org.jfree.util.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import com.bbva.gptf.back.transformador.ResultSetToInstrumentoTypeTransformador;
import com.bbva.gptf.dto.bean.InstrumentoType;
import com.bbva.gptf.dto.calculos.ISpCalcularGrupo;

/**
 * @author Javier Estrella.
 */
@Component
@Configurable
public class SpCalcGrupo implements ISpCalcularGrupo {
				
	private JdbcTemplate jdbcTemplate;
	
	private DataSource dataSource;
	
	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	
	@SuppressWarnings("unchecked")
	public List<InstrumentoType> execute(final Object[][] listaObjetos) {
		List<InstrumentoType> instrumentos = new ArrayList<InstrumentoType>();
		try {
			final String procedureName = "PKG_GPT.SP_CALC_GRUPO";
			this.jdbcTemplate = new JdbcTemplate(this.dataSource);
			Object objeto = jdbcTemplate.execute(
					new CallableStatementCreator() {
						public CallableStatement createCallableStatement(Connection con) throws SQLException{
							Connection dcon = ((DelegatingConnection) con).getInnermostDelegate();
							ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("TP_TBL_INSTRUMEN", dcon);
							ARRAY arrayParametro = new ARRAY(arrayDescriptor, dcon, listaObjetos);
							CallableStatement cs = con.prepareCall("{call " + procedureName + "(?,?)}" );
							cs.setArray(1, arrayParametro);
							cs.registerOutParameter(2, OracleTypes.CURSOR);
							return cs;
						}
					},
					new CallableStatementCallback<Object>() {
						public Object doInCallableStatement(CallableStatement cs) throws SQLException{
							cs.execute();							
							ResultSet rs = (ResultSet) cs.getObject(2);
							ResultSetToInstrumentoTypeTransformador transformador = new ResultSetToInstrumentoTypeTransformador();
							List<InstrumentoType> instrumentos = transformador.convert(rs);
							return (Object)instrumentos;
						}
					});
			instrumentos = (List<InstrumentoType>) objeto;
		} catch (Exception e) {
			Log.info(e.toString());
		}
		return instrumentos;
	}
}
